/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.edit;

import static com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil.getCovereds;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.draw2d.IFigure;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.gef.EditPolicy;
import org.eclipse.uml2.uml.Continuation;
import org.eclipse.uml2.uml.Lifeline;

import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.utils.LookForElement;
import com.cea.papyrus.diagram.sequence.sedi.edit.policy.DeletionEditPolicy;
import com.cea.papyrus.diagram.sequence.sedi.figures.AnchorContributor;
import com.cea.papyrus.diagram.sequence.sedi.figures.AnchoringFigure;
import com.cea.papyrus.diagram.sequence.sedi.figures.ContinuationFigure;
import com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;

/**
 * Edit part for Continuation.
 * 
 * @author Andreas Limyr
 * @author frankd@ifi.uio.no
 */
public class ContinuationEditPart extends AnchoringEditPart<Continuation> {

    public ContinuationEditPart(GraphElement view, ModelManager modelManager) {
        super(view, modelManager);
    }

    @Override
    protected IFigure createFigure() {
        return new ContinuationFigure();
    }

    @Override
    protected void createEditPolicies() {
        super.createEditPolicies();

        // Add edit policy to handle deletion requests (replace SeDiSubpartEditPolicy)
		installEditPolicy(
				EditPolicy.COMPONENT_ROLE,
		        new DeletionEditPolicy());
    }

    // TODO Anchor contribution updates should happen in commands
    // This code is also duplicated (100% identical) in IOEditPart.
    private Set<Lifeline> contributingTo = new HashSet<Lifeline>();

    @Override
    protected void refreshVisuals() {
        super.refreshVisuals();

        // Update anchor contribution to covered lifelines
        final Set<Lifeline> obsolete = new HashSet<Lifeline>(contributingTo);
        for (Lifeline lifeline : getCovereds(getUmlElement())) {
            obsolete.remove(lifeline);

            if (!contributingTo.contains(lifeline)) {
                AnchoringFigure lifelineFigure = getLifelineFigure(lifeline);
                if (lifelineFigure != null) {
                    lifelineFigure.addAnchorContributor((AnchorContributor) getFigure());
                    contributingTo.add(lifeline);
                }
            }
        }
        for (Lifeline lifeline : obsolete) {
            AnchoringFigure lifelineFigure = getLifelineFigure(lifeline);
            lifelineFigure.removeAnchorContributor((AnchorContributor) getFigure());
            contributingTo.remove(lifeline);
        }
    }

    private void removeAllAnchorContributions() {
        for (Lifeline lifeline : contributingTo) {
            AnchoringFigure lifelineFigure = getLifelineFigure(lifeline);
            if (lifelineFigure != null)
                lifelineFigure.removeAnchorContributor((AnchorContributor) getFigure());
            // else: give up, the lifeline is deleted from the diagram
        }
        contributingTo.clear();
    }

    @SuppressWarnings("unchecked")
    private AnchoringFigure getLifelineFigure(Lifeline lifeline) {
        Map<Object, AnchoringEditPart> editPartRegistry =
                (Map<Object, AnchoringEditPart>) getViewer().getEditPartRegistry();
        Diagram diagram = LookForElement.getDiagram((GraphElement) getParent().getModel());
        GraphNode lifelineView = ModelUtil.getGraphNode(lifeline, diagram);
        AnchoringEditPart lifelineEP = editPartRegistry.get(lifelineView);
        if (lifelineEP != null)
            return (AnchoringFigure) lifelineEP.getFigure();
        return null;
    }

    @Override
    public void deactivate() {
        removeAllAnchorContributions();
        super.deactivate();
    }

    /**
     * @see com.cea.papyrus.diagram.sequence.sedi.edit.AbstractEditPart#umlModelChanged(org.eclipse.emf.common.notify.Notification)
     */
    @Override
    protected void umlModelChanged(Notification evt) {
        refresh();
    }
}
